package service

import (
	

	
	
	
)

// VerifyAPREQ verifies an AP_REQ sent to the service. Returns a boolean for if the AP_REQ is valid and the client's principal name and realm.
func ( *messages.APReq,  *Settings) (bool, *credentials.Credentials, error) {
	var  *credentials.Credentials
	,  := .Verify(.Keytab, .MaxClockSkew(), .ClientAddress(), .KeytabPrincipal())
	if  != nil || ! {
		return false, , 
	}

	if .RequireHostAddr() && len(.Ticket.DecryptedEncPart.CAddr) < 1 {
		return false, ,
			messages.NewKRBError(.Ticket.SName, .Ticket.Realm, errorcode.KRB_AP_ERR_BADADDR, "ticket does not contain HostAddress values required")
	}

	// Check for replay
	 := GetReplayCache(.MaxClockSkew())
	if .IsReplay(.Ticket.SName, .Authenticator) {
		return false, ,
			messages.NewKRBError(.Ticket.SName, .Ticket.Realm, errorcode.KRB_AP_ERR_REPEAT, "replay detected")
	}

	 := credentials.NewFromPrincipalName(.Authenticator.CName, .Authenticator.CRealm)
	 = 
	.SetAuthTime(time.Now().UTC())
	.SetAuthenticated(true)
	.SetValidUntil(.Ticket.DecryptedEncPart.EndTime)

	//PAC decoding
	if !.disablePACDecoding {
		, ,  := .Ticket.GetPACType(.Keytab, .KeytabPrincipal(), .Logger())
		if  &&  != nil {
			return false, , 
		}
		if  {
			// There is a valid PAC. Adding attributes to creds
			.SetADCredentials(credentials.ADCredentials{
				GroupMembershipSIDs: .KerbValidationInfo.GetGroupMembershipSIDs(),
				LogOnTime:           .KerbValidationInfo.LogOnTime.Time(),
				LogOffTime:          .KerbValidationInfo.LogOffTime.Time(),
				PasswordLastSet:     .KerbValidationInfo.PasswordLastSet.Time(),
				EffectiveName:       .KerbValidationInfo.EffectiveName.Value,
				FullName:            .KerbValidationInfo.FullName.Value,
				UserID:              int(.KerbValidationInfo.UserID),
				PrimaryGroupID:      int(.KerbValidationInfo.PrimaryGroupID),
				LogonServer:         .KerbValidationInfo.LogonServer.Value,
				LogonDomainName:     .KerbValidationInfo.LogonDomainName.Value,
				LogonDomainID:       .KerbValidationInfo.LogonDomainID.String(),
			})
		}
	}
	return true, , nil
}